﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Zj.Blog.Domain.Interface;
using Zj.Blog.Infrastructure;
using Zj.Blog.Infrastructure.Extension;

namespace Zj.Blog.Repository
{
    public class BaseRepository<T> : IRepository<T>
        where T:class,new()
    {
        public T Find(int id)
        {
            var fieldStr = string.Join(",", typeof(T).GetProperties().Select(p => string.Format("[{0}]", p.Name)));
            string sql = string.Format("select {1} from [{0}] where Id=@Id", typeof(T).Name, fieldStr);

            T t = (T)Activator.CreateInstance(typeof(T));

            return this.ExecuteSql<T>(cmd =>
            {
                using (SqlDataReader dr = cmd.ExecuteReader())
                {
                    while (dr.Read())
                    {
                        //foreach (var prop in typeof(T).GetProperties())
                        //{
                        //    if (DBNull.Value != dr[prop.Name])
                        //    {
                        //        prop.SetValue(t, dr[prop.Name]);
                        //    }
                        //}
                        var func = dr.ToExpression<T>();
                        return func.Invoke(dr);
                    }
               
                }
                return t;
            }, sql, new SqlParameter("@Id", id));
        }

        public IQueryable<T> GetList()
        {
            throw new NotImplementedException();
        }

        private S ExecuteSql<S>(Func<SqlCommand, S> func, string sql, params SqlParameter[] paras)
        {
            using (SqlConnection myConn = new SqlConnection(StaticConst.ConnStr))
            {
                myConn.Open();
                using (SqlCommand cmd = new SqlCommand(sql, myConn))
                {
                    cmd.Parameters.AddRange(paras);
                    return func.Invoke(cmd);
                }
            }
        }
    }
}
